package com.umeox.stopwatch

import android.os.Bundle
import androidx.core.content.ContextCompat
import com.umeox.moto.watch.themes.app.ThemeAppCompatActivity
import com.umeox.stopwatch.databinding.TimerLayoutBinding
import io.reactivex.Observable
import io.reactivex.Observer
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import java.util.Locale
import java.util.concurrent.TimeUnit

class TimerActivity : ThemeAppCompatActivity() {
    private var clock = Stopwatch.createUnstarted()
    private var disposable: Disposable? = null
    private var needRecovery = false
    private lateinit var binding: TimerLayoutBinding
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = TimerLayoutBinding.inflate(layoutInflater)
        setContentView(binding.root)
        binding.btnStart.setOnClickListener { startOrPause() }
        binding.btnStop.setOnClickListener { reset() }
        resetTimeText()
    }

    @Synchronized
    private fun reset() {
        if (state != TimerState.IDLE) {
            clock.pause()
            disposable!!.dispose()
        }
        clock.stop()
        resetTimeText()
        state = TimerState.IDLE
    }

    private fun resetTimeText() {
        val time = getFormat(0)
        binding.tvTime.text = String.format("%1\$s:%2\$s.%3\$s", time, time, time)
    }

    private fun startOrPause() {
        if (state == TimerState.IDLE) {
            timerStart()
            state = TimerState.RUNNING
        } else {
            clock.pause()
            disposable?.dispose()
            state = TimerState.IDLE
        }
    }


    enum class TimerState { IDLE, RUNNING }

    private var state = TimerState.IDLE
        set(value) {
            field = value
            refreshByState()
        }

    private fun refreshByState() {
        when (state) {
            TimerState.IDLE -> {
                binding.btnStart.background = ContextCompat.getDrawable(this, R.drawable.ic_start)
            }

            TimerState.RUNNING -> {
                binding.btnStart.background = ContextCompat.getDrawable(this, R.drawable.ic_pause)
            }
        }
    }

    private fun timerStart() {
        clock.start()
        timer()
    }

    private fun timer() {
        Observable
            .interval(30, TimeUnit.MILLISECONDS)
            .observeOn(AndroidSchedulers.mainThread())
            .map { clock.elapsed(TimeUnit.MILLISECONDS) }
            .subscribe(mObserver)
    }


    private val mObserver: Observer<Long> = object : Observer<Long> {
        override fun onSubscribe(d: Disposable) {
            disposable = d
        }

        override fun onNext(time: Long) {
            var timeVar = time
            val minute = getFormat(TimeUnit.MILLISECONDS.toMinutes(timeVar))
            timeVar %= TimeUnit.MINUTES.toMillis(1)
            val seconds = getFormat(TimeUnit.MILLISECONDS.toSeconds(timeVar))
            timeVar = (timeVar % TimeUnit.SECONDS.toMillis(1)) / 10
            binding.tvTime.text = String.format("%1\$s:%2\$s.%3\$s", minute, seconds, getFormat(timeVar))
        }

        override fun onError(e: Throwable) {
        }

        override fun onComplete() {
        }
    }

    private fun getFormat(aLong: Long): String {
        return String.format(Locale.getDefault(), "%02d", aLong)
    }

    override fun onResume() {
        super.onResume()
        if (needRecovery) {
            timer()
        }
    }

    override fun onPause() {
        super.onPause()
        if (disposable != null && !disposable!!.isDisposed) {
            needRecovery = true
            disposable!!.dispose()
            disposable = null
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        if (disposable != null) {
            disposable!!.dispose()
            disposable = null
        }
    }
}
